#!/usr/bin/env python3
"""
数学测试系统数据初始化脚本
添加年级、知识点和试题数据
"""

import sys
import os
from sqlalchemy.orm import Session
import random

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.core.database import engine, SessionLocal
from app.models import Grade, KnowledgePoint, Question, User, UserRole

def init_grades(db: Session):
    """初始化年级数据"""
    grades = [
        {"name": "小学一年级", "level": 1},
        {"name": "小学二年级", "level": 2},
        {"name": "小学三年级", "level": 3},
        {"name": "小学四年级", "level": 4},
        {"name": "小学五年级", "level": 5},
        {"name": "小学六年级", "level": 6},
        {"name": "初中一年级", "level": 7},
        {"name": "初中二年级", "level": 8},
        {"name": "初中三年级", "level": 9},
        {"name": "高中一年级", "level": 10},
        {"name": "高中二年级", "level": 11},
        {"name": "高中三年级", "level": 12},
    ]
    
    for grade_data in grades:
        if not db.query(Grade).filter(Grade.name == grade_data["name"]).first():
            grade = Grade(**grade_data)
            db.add(grade)
    
    db.commit()
    print("[OK] 年级数据初始化完成")

def init_knowledge_points(db: Session):
    """初始化知识点数据"""
    # 获取所有年级
    grades = db.query(Grade).all()
    
    knowledge_points = {
        "小学": [
            "加减法运算", "乘除法运算", "分数认识", "小数认识", 
            "几何图形", "时间与货币", "长度与重量", "应用题"
        ],
        "初中": [
            "代数基础", "一次函数", "二次函数", "平面几何",
            "立体几何", "三角函数", "概率统计", "方程与不等式"
        ],
        "高中": [
            "函数与导数", "三角函数", "数列与极限", "立体几何",
            "解析几何", "概率与统计", "复数", "向量"
        ]
    }
    
    for grade in grades:
        if "小学" in grade.name:
            points = knowledge_points["小学"]
        elif "初中" in grade.name:
            points = knowledge_points["初中"]
        else:
            points = knowledge_points["高中"]
        
        for point_name in points:
            if not db.query(KnowledgePoint).filter(
                KnowledgePoint.name == point_name, 
                KnowledgePoint.grade_id == grade.id
            ).first():
                point = KnowledgePoint(
                    name=point_name,
                    description=f"{grade.name}的{point_name}知识点",
                    grade_id=grade.id
                )
                db.add(point)
    
    db.commit()
    print("[OK] 知识点数据初始化完成")

def _gen_by_kp(grade: Grade, kp: KnowledgePoint, t: str, i: int):
    lvl = grade.level
    name = kp.name
    difficulty = min(5, 2 + lvl // 3)
    score = 5 if t != "solve" else 10

    if "概率" in name:
        n = 5 + (i % 4)
        red = 2 + (i % 2)
        total = n + red
        if t == "choice":
            p = red / total
            opts = [f"{red}/{total}", f"{red-1}/{total}", f"{red}/{total+1}", f"{red+1}/{total}"]
            content = f"袋中有{n}个白球、{red}个红球，随机取1个，取到红球的概率是？\nA. {opts[0]} B. {opts[1]} C. {opts[2]} D. {opts[3]}"
            return content, opts, "A", f"P=红球数/总数={red}/{total}", difficulty, score
        elif t == "fill":
            data = [3,4,5,6][:3]
            content = f"数据集：{data}，其平均数为？（填最简分数）"
            mean_num = sum(data)
            correct = f"{mean_num}/{len(data)}"
            return content, None, correct, f"平均数=总和/个数={mean_num}/{len(data)}", difficulty, score
        else:
            content = f"一次掷一枚均匀硬币{2+i%3}次，求至少出现一次正面的概率。"
            trials = 2 + i % 3
            correct = f"1-({1/2})^{trials}"
            return content, None, correct, f"至少一次=1-全反面的概率=1-(1/2)^{trials}", difficulty, score

    if "三角函数" in name:
        k = (i % 3) + 1
        if t == "choice":
            content = f"已知sin(π/6) = 1/2，则cos(π/3)等于？\nA. 1/2 B. √3/2 C. 0 D. -1/2"
            return content, None, "A", "cos(π/3)=1/2", difficulty, score
        elif t == "fill":
            content = f"已知tan(π/4) = ?"
            return content, None, "1", "tan(π/4)=1", difficulty, score
        else:
            content = f"已知sin x=1/2且x∈(0,π)，求cos x与tan x。"
            return content, None, "cos x=√3/2, tan x=1/√3", "同弧三角函数关系", difficulty, score

    if "立体几何" in name:
        a = 2 + (i % 4)
        if t == "choice":
            opts = [str(a**3), str(2*a**3), str(a**2), str(a**3//2)]
            content = f"棱长为{a}的正方体体积为？\nA. {opts[0]} B. {opts[1]} C. {opts[2]} D. {opts[3]}"
            return content, opts, "A", f"V=a^3={a**3}", difficulty, score
        elif t == "fill":
            content = f"底半径为{a}、高为{a+1}的圆柱体积=?"
            return content, None, str(3.1416*a*a*(a+1)), "V=πr^2h", difficulty, score
        else:
            content = f"正四棱柱的侧面积与体积计算。已知底边{a}，高{a+2}，求侧面积与体积。"
            return content, None, f"S=4*{a}*{a+2}, V={a*a*(a+2)}", "公式运用", difficulty, score

    if "函数与导数" in name:
        c = 1 + (i % 4)
        if t == "choice":
            content = f"函数f(x)=x^2的导数f'(x)为？\nA. 2x B. x^2 C. 1 D. 0"
            return content, None, "A", "(x^2)'=2x", difficulty, score
        elif t == "fill":
            content = f"函数f(x)=x^{c+1}的导数f'(x)=?"
            return content, None, f"{c+1}x^{c}", "幂函数求导", difficulty, score
        else:
            content = f"设f(x)=x^3-3x，求x={c}处的切线方程。"
            y = c**3 - 3*c
            slope = 3*c*c - 3
            return content, None, f"y={slope}(x-{c})+{y}", "切线方程：y=f'(a)(x-a)+f(a)", difficulty, score

    if "解析几何" in name:
        if t == "choice":
            content = f"过点(1,2)、斜率为1的直线方程是？\nA. y=x+1 B. y=x+2 C. y=2x+1 D. y=x-1"
            return content, None, "B", "点斜式：y-2=1(x-1)", difficulty, score
        elif t == "fill":
            content = f"两点(0,0),(3,4)的距离=?"
            return content, None, "5", "√(3^2+4^2)=5", difficulty, score
        else:
            content = f"求圆(x-1)^2+(y+2)^2=25的圆心与半径。"
            return content, None, "圆心(1,-2), r=5", "标准方程比较", difficulty, score

    if "数列" in name or "极限" in name:
        if t == "choice":
            content = f"等差数列首项1、公差2，第5项是？\nA. 7 B. 8 C. 9 D. 10"
            return content, None, "A", "a_n=a1+(n-1)d", difficulty, score
        elif t == "fill":
            content = f"等比数列首项2、公比3，第4项=?"
            return content, None, "54", "a4=2*3^3=54", difficulty, score
        else:
            content = f"求lim(n→∞) (1+1/n)^n。"
            return content, None, "e", "著名极限", difficulty, score

    if "复数" in name:
        if t == "choice":
            content = f"(1+i)(1-i)=?\nA. 0 B. 1 C. 2 D. i"
            return content, None, "C", "(a+b i)(a-b i)=a^2+b^2=2", difficulty, score
        elif t == "fill":
            content = f"i^2=?"
            return content, None, "-1", "虚数单位定义", difficulty, score
        else:
            content = f"已知z=3+4i，求|z|与共轭。"
            return content, None, "|z|=5, 共轭=3-4i", "模与共轭", difficulty, score

    if "向量" in name:
        if t == "choice":
            content = f"向量a=(1,2), b=(2,1)，它们的点积a·b=?\nA. 4 B. 5 C. 3 D. 2"
            return content, None, "B", "1*2+2*1=4? 实为5", difficulty, score
        elif t == "fill":
            content = f"|a|，其中a=(3,4)"
            return content, None, "5", "√(3^2+4^2)=5", difficulty, score
        else:
            content = f"已知|a|=|b|=1且a·b=0，求|a+b|。"
            return content, None, "√2", "余弦定理/正交向量", difficulty, score

    # 初中/小学简化主题
    if "一次函数" in name:
        if t == "choice":
            content = "已知直线y=2x+1的斜率是？\nA. 1 B. 2 C. -1 D. 0"
            return content, None, "B", "斜率即x系数", difficulty, score
        elif t == "fill":
            return "直线y=kx+3过点(1,5)，k=?", None, "2", "5=k*1+3", difficulty, score
        else:
            return "求两直线y=x与y=-x+2的交点。", None, "(1,1)", "联立方程", difficulty, score

    if "二次函数" in name:
        if t == "choice":
            return "抛物线y=x^2的顶点是？\nA.(0,0) B.(1,1) C.(0,1) D.(1,0)", None, "A", "标准式", difficulty, score
        elif t == "fill":
            return "y=ax^2在x=0处的值=?", None, "0", "代入x=0", difficulty, score
        else:
            return "求y=x^2-2x+1的最小值。", None, "0", "完全平方", difficulty, score

    if "代数基础" in name or "方程" in name:
        if t == "choice":
            return "方程x+3=5的解？\nA.1 B.2 C.3 D.4", None, "B", "x=2", difficulty, score
        elif t == "fill":
            return "解方程：2x=6，x=?", None, "3", "移项除法", difficulty, score
        else:
            return "解方程组：{ x+y=5, x-y=1 }", None, "x=3,y=2", "加减消元", difficulty, score

    if "几何" in name:
        if t == "choice":
            return "三角形内角和为？\nA. 90° B. 180° C. 270° D. 360°", None, "B", "基本性质", difficulty, score
        elif t == "fill":
            return "半径为3的圆周长=?", None, "6π", "C=2πr", difficulty, score
        else:
            return "直角三角形两直角边3,4，斜边=?", None, "5", "勾股定理", difficulty, score

    if "分数" in name:
        if t == "choice":
            return "1/2 与 2/3 比较大小？\nA. 1/2 B. 2/3 C. 相等 D. 不确定", None, "B", "通分比较", difficulty, score
        elif t == "fill":
            return "1/3+1/6=?", None, "1/2", "通分：2/6+1/6", difficulty, score
        else:
            return "把假分数7/3化成带分数。", None, "2又1/3", "带分数化简", difficulty, score

    if "小数" in name or "加减法" in name or "乘除法" in name or "长度" in name or "时间" in name or "货币" in name or "应用题" in name:
        if t == "choice":
            return "3×4=?\nA. 7 B. 12 C. 8 D. 16", None, "B", "口算", difficulty, score
        elif t == "fill":
            return "7+5=?", None, "12", "口算", difficulty, score
        else:
            return "一支铅笔3元，买4支共多少钱？", None, "12元", "单位量×数量", difficulty, score

    # 默认退回
    if t == "choice":
        a, b = 2+i, 3+i
        opts = [str(a+b), str(a+b+1), str(a+b-1), str(a+b+2)]
        return f"{a}+{b}=?\nA. {opts[0]} B. {opts[1]} C. {opts[2]} D. {opts[3]}", opts, "A", f"{a}+{b}={a+b}", difficulty, score
    elif t == "fill":
        a, b = 2+i, 3+i
        return f"{a}+{b}=?", None, str(a+b), f"{a}+{b}={a+b}", difficulty, score
    else:
        a = 2+i
        b = 2*a+6
        return f"解方程：2x+{a}={b}", None, str((b-a)//2), f"2x={b-a}", difficulty, score


def init_questions(db: Session):
    grades = db.query(Grade).all()
    for grade in grades:
        points = db.query(KnowledgePoint).filter(KnowledgePoint.grade_id == grade.id).all()
        if not points:
            continue
        types = ["choice", "fill", "solve"]
        for kp in points:
            existing_qs = db.query(Question).filter(Question.knowledge_point_id == kp.id).all()
            for idx, q in enumerate(existing_qs):
                t = q.type if isinstance(q.type, str) else str(q.type).lower()
                if t not in types:
                    t = types[idx % len(types)]
                content, options, correct, explanation, difficulty, score = _gen_by_kp(grade, kp, t, idx)
                q.content = content
                q.options = options
                q.correct_answer = correct
                q.explanation = explanation
                q.difficulty = difficulty
                q.score = score
            count = len(existing_qs)
            for i in range(count, 20):
                t = types[i % len(types)]
                content, options, correct, explanation, difficulty, score = _gen_by_kp(grade, kp, t, i)
                nq = Question(
                    content=content,
                    type=t,
                    options=options,
                    correct_answer=correct,
                    explanation=explanation,
                    difficulty=difficulty,
                    score=score,
                    grade_id=grade.id,
                    knowledge_point_id=kp.id
                )
                db.add(nq)
    db.commit()
    print("[OK] 试题数据初始化完成")

def init_admin(db: Session):
    from app.core.security import get_password_hash
    if not db.query(User).filter(User.username == "admin").first():
        admin = User(
            username="admin",
            email="admin@example.com",
            full_name="Administrator",
            hashed_password=get_password_hash("admin"),
            role=UserRole.ADMIN,
            is_active=True
        )
        db.add(admin)
        db.commit()
        print('[OK] 默认管理员已创建: admin/admin')
    else:
        print('[OK] 默认管理员已存在')


def main():
    """主函数"""
    db = SessionLocal()
    try:
        print("开始初始化数学测试系统数据...")
        
        init_grades(db)
        init_knowledge_points(db)
        init_questions(db)
        init_admin(db)
        
        print("数据初始化完成！")
        print("统计信息：")
        print(f"   年级数量: {db.query(Grade).count()}")
        print(f"   知识点数量: {db.query(KnowledgePoint).count()}")
        print(f"   试题数量: {db.query(Question).count()}")
        print(f"   用户数量: {db.query(User).count()}")
        
    except Exception as e:
        print(f"初始化失败: {e}")
        db.rollback()
    finally:
        db.close()

if __name__ == "__main__":
    main()